/*
 * Copyright (c) 2025 HiSilicon (Shanghai) Technologies Co., Ltd.
*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef OT_PDAF_H
#define OT_PDAF_H

#include "ot_af_common.h"
#include "ot_common_video.h"

#define OT_PDAF_DSP_CORE_NUM 2
#define OT_PDAF_DSP_BIN_NUM 4

typedef enum { // 错误码
    OT_ERR_PDAF_OK = 0,
    OT_ERR_PDAF_NOT_SUPPORT,   // 当前功能或者配置不支持
    OT_ERR_PDAF_EXIST,         // 重复创建已存在的资源
    OT_ERR_PDAF_UNEXIST,       // 试图使用或销毁不存在的资源
    OT_ERR_PDAF_ILLEGAL_PARAM, // 非法参数
    OT_ERR_PDAF_NULL_PTR,      // 空指针
    OT_ERR_PDAF_FAILURE,       // 失败
    OT_ERR_PDAF_BUTT,
} OT_PDAF_ErrorCode;

typedef enum {
    PP_HALF_SHIELD = 0,
    PP_DUAL,
    PP_QUAD,
    PP_TYPE_BUTT,
} OT_PDAF_PPType;

typedef enum {
    PD_OUT_H = 0,
    PD_OUT_V,
    PD_OUT_BUTT,
} OT_PDAF_OutType;

typedef enum {
    USE_FOR_FOCUS = 0,
    USE_FOR_CALIBRATION,
    USE_FOR_BUTT,
} OT_PDAF_UseType;

typedef enum {
    PD_CONCATE_HOR = 0, // 水平连接
    PD_CONCATE_VER,     // 垂直连接
    PD_CONCATE_BUTT,
} OT_PDAF_ConcateType;

typedef enum {
    PD_METHOD_TYPE0 = 0, // pd计算方法1
    PD_METHOD_TYPE1,     // pd计算方法2
    PD_METHOD_TYPE2,
    PD_METHOD_BUTT,
} OT_PDAF_MethodType;

typedef struct {
    td_s32 (*init)(td_void);
    td_s32 (*deinit)(td_void);
    td_s32 (*getDccOffset)(const OT_AF_OpticsInfo *optics, OT_AF_PDAFCaliData *offset);
} OT_PDAF_CalibDataMgrIntf;

typedef struct {
    td_s32 (*init)(td_void);
    td_s32 (*deinit)(td_void);
    td_s32 (*preprocessFrame)(const OT_AF_OpticsInfo *optics, ot_video_frame_info *frame);
    td_s32 (*releasePreFrame)(const ot_video_frame_info *frame);
} OT_AF_PreprocessAlgIntf;

typedef struct {
    td_s32 (*init)(ot_vi_pipe pipe);
    td_s32 (*deinit)(td_void);
    td_s32 (*separateFrame)(ot_video_frame_info *frame);
    td_s32 (*releaseSepFrame)(const ot_video_frame_info *frame);
} OT_AF_SeparateAlgIntf;

typedef struct {
    OT_PDAF_UseType useType; // 用途，用于对焦 还是标定
    /* description of pp information */
    OT_PDAF_PPType ppType;           //  pp 类型
    OT_PDAF_ConcateType concateType; // 拼接方式
    OT_PDAF_MethodType pdMethod;     // pd计算方法
    td_u32 maxPDValue;               // 最大的pd值
    td_s32 maxCode;                  // code 最大值和最小值，外部传入
    td_s32 minCode;
    ot_size originSize; // 原始图大小
    ot_size ppSize;     // 传进来的 pp图大小，左右拼接或者上下拼接后的尺寸。
    OT_PDAF_CalibDataMgrIntf calibMgr;
    OT_AF_PreprocessAlgIntf preprocess;
    td_bool useDsp;
    td_bool enableLumaDiff;
    td_char *dspBinPath[OT_PDAF_DSP_CORE_NUM][OT_PDAF_DSP_BIN_NUM];
} OT_PDAF_InitParam;

typedef struct {
    OT_AF_OpticsInfo *optics;
    OT_AF_WindowConfig windowConfig;
    td_s32 maxCode; // code 最大值和最小值，外部传入
    td_s32 minCode;
    td_s32 curCode; // 优化搜索空间
} OT_PDAF_Param;

typedef struct {
    td_float pdValue;
    td_s32 defocus;
    td_u32 pdConfidence;
    td_u32 defocusConfidence;
    td_s32 focusCode;
    td_float dcc;
    td_float lumaDiff;
    td_u32 peakLen; // 多峰的数量
} OT_PDAF_Result;

typedef struct {
    OT_PDAF_Result fixed[MAX_FIXED_WINDOW_HEIGHT_NUM][MAX_FIXED_WINDOW_WIDTH_NUM];
    OT_PDAF_Result flexible[MAX_FLEXIBLE_WINDOW_NUM];
} OT_PDAF_Out;

typedef struct {
    td_u64 pts;
    OT_PDAF_Out out[PD_OUT_BUTT];
} OT_PDAF_Results;

typedef enum {
    PDAF_LOG_ERR_LEVEL_DEBUG = 0, /* debug-level                                  */
    PDAF_LOG_ERR_LEVEL_INFO,      /* informational                                */
    PDAF_LOG_ERR_LEVEL_NOTICE,    /* normal but significant condition             */
    PDAF_LOG_ERR_LEVEL_WARNING,   /* warning conditions                           */
    PDAF_LOG_ERR_LEVEL_ERROR,     /* error conditions                             */
    PDAF_LOG_ERR_LEVEL_FATAL,
    PDAF_LOG_ERR_LEVEL_BUTT
} OT_PDAF_LogErrorLevel;

typedef struct {
    OT_AF_AlgInfo info;
    td_s32 (*init)(td_void **handle, const OT_PDAF_InitParam *pdInitParam);
    td_s32 (*deinit)(td_void *handle);
    td_s32 (*process)(td_void *handle, const OT_PDAF_Param *pdParam, OT_PDAF_Results *results);
    td_s32 (*setLogLevel)(OT_PDAF_LogErrorLevel logLevel);
} OT_AF_PDAFAlgIntf;

OT_AF_PDAFAlgIntf *SS_PDAF_GetAlg(td_void);

#endif
